#include "tContainer_t.h"
#include <list>
#include <iostream>
#include <string>

void Tester_insert(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	int val = 0;
	cout<<"Please enter an integer value"<<endl;
	cin>>val;
	int * i = new int(val);
	bool success;
	if (choice=="v")
		 success = vec->insertAtEnd(i);
	else 
		 success = ls->insertAtEnd(i);

	if (success) 
		cout<<"Element inserted"<<endl;
	else
		cout<<"Can't insert element"<<endl;
}
void Tester_Empty(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	if (choice=="v"){
		if(vec->isEmpty())
			cout << "Vector is empty" << endl;	
		else
			cout << "Vector is not empty" << endl;	
	}
	else {
		if(ls->isEmpty())
			cout << "Vector is empty" << endl;
		else
			cout << "Vector is not empty" << endl;	
	}
}


void Tester_NumOfElem(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	if (choice=="v")
		cout<<"The number of elements is "<<vec->getNumOfElements()<<endl;
	else 
		cout<<"The number of elements is "<<ls->getNumOfElements()<<endl;
}
void Tester_rall(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	if (choice=="v"){
		vec->removeAllElements();
		if(vec->isEmpty())
			cout << "All elements removed" << endl;
		else
			cout << "Error: can't rmove all elemets" << endl;
	}
	else {
		ls->removeAllElements();
		if(ls->isEmpty())
			cout << "All elements removed" << endl;
		else
			cout << "Error: can't rmove all elemets" << endl;
	}
}

void Tester_first(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	int * i;	
	if (choice=="v")
		i = (int*)vec->getFirstElement();
	else 
		i = (int*)ls->getFirstElement();
	cout << "The first elemnt is: " << *i << endl;
}

void Tester_rdall(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	if (choice=="v"){
		vec->removeAndDeleteAllElements();
		if(vec->isEmpty())
			cout << "All elements removed" << endl;
		else
			cout << "Error: can't rmove all elemets" << endl;
	}
	else { 
		ls->removeAndDeleteAllElements();
		if(ls->isEmpty())
			cout << "All elements removed" << endl;
		else
			cout << "Error: can't rmove all elemets" << endl;
	}
}

void Tester_find(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	int val = 0;
	cout<<"Please enter a value to find in the container"<<endl;
	cin>>val;
	int *i;
	if (choice=="v")
		i = (int*)vec->findByValue(val);
	else 
		i = (int*)ls->findByValue(val);
	
	if(i != 0)
		cout << "Element found" << endl;
	else
		cout << "Element not found" << endl;
}

void Tester_rdspec(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	int val = 0;
	cout<<"Please enter a value to find in the container"<<endl;
	cin>>val;
	if (choice=="v"){
		if(vec->removeAndDeleteSpecificElement(val))
			cout << "Element deleted" << endl;
		else
			cout << "Deletion failed - element does not exist" << endl;
	}
	else { 
		if(ls->removeAndDeleteSpecificElement(val))
			cout << "Element deleted" << endl;
		else
			cout << "Deletion failed - element does not exist" << endl;
	}
}
void Tester_rspec(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	int val = 0;
	cout<<"Please enter a value to find in the container"<<endl;
	cin>>val;
	if (choice=="v") { 
		int * i = (int*)vec->removeAndReturnPointer(val);
		cout << "Element removed. The value of the pointer returned is " << *i << endl;
	}
	else  {
		int * i = (int*)ls->removeAndReturnPointer(val);
		cout << "Element removed. The value of the pointer returned is " << *i << endl;
	}
}

void Tester_brackets(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	try{
		int index = -1;
		cout<<"Please enter an index to find in the container"<<endl;
		cin>>index;
		if (choice=="v") { 
			int * i = (int*)vec->operator[](index);
			cout<<"The value in index "<<index<< " is "<<*i<<endl;
		}
		else  {
			int * i = (int*)ls->operator[](index);
			cout<<"The value in index "<<index<< " is "<<*i<<endl;
		}
	}
	catch(std::out_of_range) {
		cout<<"Index is out of range"<<endl;
		return;
	}
}



void Tester_last(tContainer_t<int,vector<int*>>* vec,tContainer_t<int,list<int*>>* ls,string& choice){
	int *i;
	if (choice=="v")
		i = (int*)vec->getLastElement();
	else 
		i = (int*)ls->getLastElement();
	cout << "The last elemnt is: " << *i << endl;
}


int main() { 	
	tContainer_t<int,list<int*>>* l = new tContainer_t<int,list<int*>>;
	tContainer_t<int,vector<int*>>* v = new tContainer_t<int,vector<int*>>;
	string choice = "";
	string command = "";
	cout<< "Hello and welcome to Exercise 3 Tester"<<endl;
	cout<< "To test the program with a vector consists of int pointers type \"v\""<<endl;
	cout<< "To test the program with a list consists of int pointers type \"l\""<<endl;
	std::cin>>choice;
	if (!(choice=="v"||choice=="l")){
		cout<<"Inavlid command";
	}
	else {
			cout<<"Type \"insert\" to insert an element at the end of the container"<<endl;
			cout<<"Type \"empty\" to check whteher the container is empty"<<endl;
			cout<<"type \"num\" to get the number of elemnts in the container"<<endl;
			cout<<"Type \"first\" to get the first element"<<endl;
			cout<<"Type \"last\" to get the last element"<<endl;
			cout<<"Type \"rdall\" to remove and delete all the elements"<<endl;
			cout<<"Type \"find\" to find a specific element by it's value"<<endl;
			cout<<"Type \"rdspec\" to remove and delete a specific element"<<endl;
			cout<<"Type \"rspec\" to remove and return a pointer to a specific element"<<endl;
			cout<<"Type \"rall\" to remove all elements"<<endl;
			cout<<"Type \"[]\" to get a specific element by it's index"<<endl;
			cout<<"Type \"switch\" to switch between vector and list"<<endl;
		while(1) { 
			cout<<"Please enter your command"<<endl;
			cin>>command; 
			if (command.compare("insert")==0){
				Tester_insert(v,l,choice);
			}
			else if (command.compare("empty")==0){
				Tester_Empty(v,l,choice);
			}
			else if (command.compare("num") == 0){
				Tester_NumOfElem(v,l,choice);
			}
		
			else if (command.compare("first") == 0){
				Tester_first(v,l,choice);
			}
			else if (command.compare("last") == 0){
				Tester_last(v,l,choice);
			}
			else if (command.compare("rdall") == 0){
				Tester_rdall(v,l,choice);
			}

			else if (command.compare("find") == 0){
				Tester_find(v,l,choice);
			}
			else if (command.compare("rdspec") == 0){
				Tester_rdspec(v,l,choice);
			}
			else if (command.compare("rspec") == 0){
				Tester_rspec(v,l,choice);
			}
			else if (command.compare("rall") == 0){
				Tester_rall(v,l,choice);
			}
			else if (command.compare("[]") == 0){
				Tester_brackets(v,l,choice);
			}
			else if (command.compare("exit") == 0){
				cout << "Good bye, see you later" <<endl;
				delete(l);
				delete(v);
				exit(0);
			}
			else if (command.compare("switch") == 0){
				cout<< "To switch to the vector type \"v\""<<endl;
				cout<< "To switch to the list type type \"l\""<<endl;
				cin>>choice;
				continue;
				
			}
			else (cout<<"Invalid command"<<endl);
		}
	}
}
